﻿//===============================================================================
// Microsoft patterns & practices
// Windows Phone 7 Developer Guide
//===============================================================================
// Copyright © Microsoft Corporation.  All rights reserved.
// This code released under the terms of the 
// Microsoft patterns & practices license (http://wp7guide.codeplex.com/license)
//===============================================================================


namespace AzureToolkit
{
    using System.Collections.Generic;
    using System.Data.Services.Client;
    using System.Linq;
    using Microsoft.WindowsAzure;
    using Microsoft.WindowsAzure.StorageClient;

    public class AzureTable<T> : AzureTableBase<T>, IInitializer where T : TableServiceEntity
    {

        public AzureTable()
            : this(CloudConfiguration.GetStorageAccount())
        {
        }

        public AzureTable(CloudStorageAccount account)
            : this(account, null)
        {
        }

        public AzureTable(CloudStorageAccount account, string tableName)
            : base(account, tableName)
        {
        }

        public override void AddOrUpdate(IEnumerable<T> objs)
        {
            foreach (var obj in objs)
            {
                T objCopy = obj;
                try
                {
                    var existingObj = (from o in this.Query
                                       where o.RowKey == objCopy.RowKey
                                             && o.PartitionKey == objCopy.PartitionKey
                                       select o).SingleOrDefault();
                    if (existingObj == null)
                    {
                        this.Add(obj);
                    }
                    else
                    {
                        TableServiceContext context = this.CreateContext();
                        context.AttachTo(TableName, obj, "*");
                        context.UpdateObject(obj);
                        context.SaveChanges(SaveChangesOptions.ReplaceOnUpdate);
                    }
                }
                catch (DataServiceQueryException ex)
                {
                    var dataServiceClientException = ex.InnerException as DataServiceClientException;
                    if (dataServiceClientException != null)
                    {
                        if (dataServiceClientException.StatusCode == 404)
                        {
                            this.Add(obj);
                        }
                        else
                        {
                            throw;
                        }
                    }
                    else
                    {
                        throw;
                    }
                }
            }
        }

    }
}